home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / COMM / INTERNET / TELNET / RLOGIND / !RloginD / telnet / rxtelnet_c < prev    next >
Text File  |  1993-09-02  |  7KB  |  333 lines

  1. /* > rxtelnet.c
  2. ** (C) 1993 Andrew Brooks, arb@comp.lancs.ac.uk
  3. ** 7 Kennedy Close, Newton, Chester, CH2 2PL.
  4. ** Version 1.50 - Thu 02 Sep 11:52:11 WET DST 1993
  5. **
  6. ** Full-duplex remote-login server
  7. **   Understands very limited set of telnet commands.
  8. **   Sends logout command when connection is dropped.
  9. **   Option LOG_CHARS to log all chars passing through in both directions.
  10. **   Option ESCAPED_CHARS to recognise escaped control chars from remote host.
  11. **   Option STRIP14 to strip character 14 from Archimedes (Enable Paged Mode)
  12. **     which messes up some terminal emulators.
  13. **   Option DEL2BS to convert Delete to Backspace (127 to 8).
  14. **   Program can be quit using Ctrl-C only when no clients are connected.
  15. */
  16.  
  17. static char SCCSid[] = "@(#)rxtelnet.c    1.50 (C) 1993 arb RLoginD telnet server";
  18.  
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <sys/file.h>
  22. #include <netinet/in.h>
  23. #include <netdb.h>
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <signal.h>
  27. #ifdef SIGCLD
  28. #define SIGCHILD SIGCLD
  29. #endif
  30. #ifdef SIGCHLD
  31. #define SIGCHILD SIGCHLD
  32. #endif
  33.  
  34. #include "term.h"
  35. TERM_STRUCT termbuf;
  36.  
  37. #define EXIT(A) { atexit(); exit(A); }
  38. #define ERR_FILE "rx_log"
  39. #define ESCAPE 27
  40. #define DEL 127
  41. #define BS 8
  42. #define CMD_LOGOUT 2
  43.  
  44. #ifdef LOG_CHARS
  45. #define PR(x) (isascii(x)&&isprint(x)?x:'.')
  46. void
  47. log_char(fname, ch)
  48. char *fname;
  49. unsigned int ch;
  50. {
  51.     FILE *fp=fopen(fname,"a");
  52.     if (fp==NULL) fprintf(stderr,"Warning: could not open file %s\n",fname);
  53.     else
  54.     {
  55.         fprintf(fp,"%s:  %c  %8x  %d\n",fname, PR(ch), ch, ch);
  56.         fclose(fp);
  57.     }
  58. }
  59. #endif
  60.  
  61.  
  62. void
  63. reap()
  64. {
  65.     wait();
  66. }
  67.  
  68.  
  69. void
  70. atexit()
  71. {
  72.     /* called just before exit() */
  73.     /* restore old terminal state */
  74.     Term_Restore(0,&termbuf);
  75. }
  76.  
  77.  
  78. void
  79. quit()
  80. /* called when program interrupted, eg. ^C */
  81. {
  82.     fprintf(stderr,"Quit...\n");                    /* goes to log file */
  83.     EXIT(1);
  84. }
  85.  
  86.  
  87. int
  88. read_from_socket(sock, buf)
  89. int sock;
  90. char *buf;
  91. {
  92.     int num;
  93.     /* reads one byte, returns number of bytes read (ie. 1 if successful) */
  94.     num=read(sock,buf,1);
  95.     if (num<1)
  96.     {
  97.         if (num!=0) 
  98.             perror("Cannot read from remote login user socket");
  99.         else
  100.             fprintf(stderr,"Remote user logged out\n");
  101.         close(sock);
  102.         num=0;
  103.     }
  104. #ifdef LOG_CHARS
  105.     log_char("toarc_log", *buf);
  106. #endif
  107.     return(num);
  108. }
  109.  
  110.  
  111. int
  112. write_to_stdout(buf)
  113. char *buf;
  114. {
  115.     int num;
  116.     num = write(1,buf,1);
  117.     if (num<1)
  118.     {
  119.         perror("Cannot write to remote machine");
  120.         num=0;
  121.     }
  122.     return(num);
  123. }
  124.  
  125.  
  126. int
  127. read_from_stdin(buf)
  128. char *buf;
  129. {
  130.     /* read from remote machine.  strip esc and add 32 to following char */
  131.     int num;
  132.     num = read(0,buf,1);
  133.  
  134. #ifdef DEL2BS
  135.     if (*buf == DEL) *buf = BS;
  136. #endif
  137.     if (num<1)
  138.     {
  139.         perror("Cannot read from remote machine's kbd");
  140.         num=0;
  141.     }
  142. #ifdef ESCAPED_CHARS
  143.     else if (*buf == ESCAPE)
  144.     {
  145.         num = read(0,buf,1);
  146.         if (num<1)
  147.         {
  148.             perror("Cannot read from remote machine's kbd");
  149.             num=0;
  150.         }
  151.         *buf = (*buf)+32;
  152.     }
  153. #endif
  154. #ifdef LOG_CHARS
  155.     log_char("fromarc_log", *buf);
  156. #endif
  157.     return(num);
  158. }
  159.  
  160.  
  161. int
  162. write_to_socket(sock, buf)
  163. int sock;
  164. char *buf;
  165. {
  166.     int num;
  167. #ifdef STRIP14
  168.     if (*buf == 14) return(1);
  169. #endif
  170.     num = write(sock, buf, 1);
  171.     if (num<1)
  172.     {
  173.         perror("Cannot write to remote login user socket");
  174.         num=0;
  175.     }
  176.     return(num);
  177. }
  178.  
  179.  
  180. void
  181. telnet_command(cmd)
  182. int cmd;
  183. {
  184.     switch (cmd)
  185.     {
  186.         case 1:
  187.             fprintf(stderr,"Telnet command 1\n");
  188.             break;
  189.         case 3:
  190.             fprintf(stderr,"Telnet command 3\n");
  191.             break;
  192.         default:
  193.             fprintf(stderr,"Unknown telnet command\n");
  194.             break;
  195.     }
  196. }
  197.  
  198.  
  199. int
  200. main(argc,argv)
  201. int argc;
  202. char* argv[];
  203. {
  204.     int sock, newsock;                    /* wait and connection sockets */
  205.     struct sockaddr_in server;            /* sock details */
  206.     struct sockaddr_in from;              /* newsock (client) details */
  207.     int fromLength;                       /* length of from */
  208.     int child;                            /* child's process id */
  209.     int errfd;                            /* error log file descriptor */
  210.     unsigned char inbyte[2], outbyte[2];  /* input and output bytes */
  211.     struct hostent *remotehost;
  212.     char *remotehostname;
  213.  
  214.     Term_Save(0,&termbuf);
  215.     signal(SIGHUP, quit);
  216.     signal(SIGINT, quit);
  217.     signal(SIGQUIT, quit);
  218.     signal(SIGTERM, quit);
  219.     signal(SIGCHILD, reap);
  220.     Term_NoEcho(0);
  221.  
  222.     if (argc!=1)
  223.     {
  224.         fprintf(stderr,"%s: Archimedes telnet server - no paramaters\n");
  225.         EXIT(1);
  226.     }
  227.  
  228.     sock=socket(AF_INET,SOCK_STREAM,0);
  229.     if (sock<0)
  230.     {
  231.         perror("Cannot create socket");
  232.         EXIT(1);
  233.     }
  234.     server.sin_family=AF_INET;
  235.     server.sin_addr.s_addr=INADDR_ANY;
  236.     server.sin_port=htons((unsigned long)PORT);
  237.     if (bind(sock,(struct sockaddr*)&server,sizeof server)<0)
  238.     {
  239.         perror("Cannot open socket");
  240.         EXIT(1);
  241.     }
  242.     if (listen(sock,0)==-1)
  243.     {
  244.         perror("Cannot listen for connections");
  245.         EXIT(1);
  246.     }
  247.     errfd=open(ERR_FILE,O_WRONLY | O_CREAT,0644);
  248.     if (errfd<0)
  249.     {
  250.         perror("Cannot open error log");
  251.         EXIT(1);
  252.     }
  253.     fprintf(stderr,"%s: logging error messages to file %s\n",argv[0],ERR_FILE);
  254.     dup2(errfd,2);                                /* errs -> log file */
  255.  
  256.     fprintf(stderr,"Starting...\n");            /* goes to log file */
  257.  
  258.     while (1)                /* accept connection, deal with it, repeat */
  259.     {
  260.         fromLength=sizeof(from);
  261.         newsock=accept(sock,(struct sockaddr*)&from,&fromLength);
  262.         if (newsock==-1)
  263.         {
  264.             perror("Cannot accept connection");
  265.             continue;
  266.         }
  267.         remotehost = gethostbyaddr(&from.sin_addr, sizeof(from.sin_addr), AF_INET);
  268.         remotehostname = remotehost ? remotehost->h_name : "unknown";
  269.         fprintf(stderr,"Accepting connection from %s on port %d\n",
  270.             remotehostname, from.sin_port);   /* need to convert ntohl ? */
  271.         switch (child=fork())
  272.         {
  273.             case -1:
  274.                 perror("Cannot create child process to handle call");
  275.                 break;
  276.             case 0:        /* child -  handle stdin and sockout */
  277.                 while (1)
  278.                 {
  279.                     if (read_from_stdin(inbyte)==0)
  280.                     {
  281.                         close(newsock);
  282.                         signal(getppid(),SIGUSR1); /* interrupt read */
  283.                         EXIT(1);
  284.                     }
  285.                     if (write_to_socket(newsock, inbyte)==0) EXIT(1);
  286.                 }
  287.                 break;
  288.             default:    /* parent - handle stdout and sockin */
  289.                 Term_Raw(0);
  290.                 while(1)
  291.                 {
  292.                     if (read_from_socket(newsock, outbyte)==0)
  293.                     {
  294.                         *outbyte = ESCAPE;
  295.                         write_to_stdout(outbyte);
  296.                         *outbyte = CMD_LOGOUT;
  297.                         write_to_stdout(outbyte);
  298.                         break;
  299.                     }
  300.                     if (*outbyte == ESCAPE)
  301.                     {
  302.                         /* Send it twice */
  303.                         if (write_to_stdout(outbyte)==0) break;
  304.                     }
  305.                     if (*outbyte == 255)
  306.                     {
  307.                         if (read_from_socket(newsock, outbyte)==0) break;
  308.                         if (*outbyte == 253)
  309.                         {
  310.                             if (read_from_socket(newsock, outbyte)==0) break;
  311.                             /* finally we have a telnet command code */
  312.                             telnet_command(*outbyte);
  313.                             continue;
  314.                         }
  315.                         else
  316.                         {
  317.                             *outbyte=255;
  318.                             if (write_to_stdout(outbyte)==0) break;
  319.                             *outbyte=253;
  320.                             if (write_to_stdout(outbyte)==0) break;
  321.                         }
  322.                     }
  323.                     if (write_to_stdout(outbyte)==0) break;
  324.                 }
  325.                 kill(child,SIGKILL);
  326.                 Term_Restore(0,&termbuf);
  327.                 Term_NoEcho(0);
  328.                 break;
  329.         }    /* end switch */
  330.     } /* end while */
  331.     return(0);
  332. }
  333.